Skip to content

ASIO: provide bufferSwitchTimeInfo instead of leaving it NULL - #486

Merged
garyscavone merged 1 commit into
thestk:masterfrom
defiantnerd:fix/asio-null-bufferswitchtimeinfo
Aug 18, 2026
Merged

ASIO: provide bufferSwitchTimeInfo instead of leaving it NULL#486
garyscavone merged 1 commit into
thestk:masterfrom
defiantnerd:fix/asio-null-bufferswitchtimeinfo

Conversation

@defiantnerd

Copy link
Copy Markdown
Contributor

Fixes #485, with the full diagnosis there. Very likely the root cause of #409
("Unstable ASIO support?"), and possibly #443.

RtApiAsio::probeDeviceOpen installs three of the four ASIO host callbacks and leaves the
fourth null:

asioCallbacks.bufferSwitch         = &bufferSwitch;
asioCallbacks.sampleRateDidChange  = &sampleRateChanged;
asioCallbacks.asioMessage          = &asioMessages;
asioCallbacks.bufferSwitchTimeInfo = NULL;

Any driver that calls bufferSwitchTimeInfo therefore transfers control to address 0 and
takes the process down. Steinberg's Generic Low Latency ASIO driver (asioglld.dll) does
this on the first ASIOStart().

asioMessages() answers kAsioSupportsTimeInfo with 0, so by the letter of the SDK a
driver should fall back to bufferSwitch. This one does not, and removing
kAsioSupportsTimeInfo from the kAsioSelectorSupported list as well does not help either
— it consults neither answer. Since the host cannot control how a third-party driver
behaves, and a call through a null function pointer is unrecoverable, the only robust option
is to supply the callback.

This is why #409's crash appears at theAsioDriver->start(): that frame is where it
surfaces, but ASIOStart() null-checks the driver pointer one line earlier. The fault is in
the driver calling back into a null host callback, so the faulting frame belongs to the
driver rather than to RtAudio.

The change

Forward bufferSwitchTimeInfo to the existing bufferSwitch; the time info is unused.
Three hunks: two forward declarations, the new function next to bufferSwitch, and the
assignment.

Verified

  • Behaviour: 15 consecutive audio-API switches cycling ASIO → WASAPI → DirectSound, five
    of them selecting ASIO, each with a live stream — no crash. Without the change the process
    dies on the first or third ASIO selection with 0xC000041D
    (STATUS_FATAL_USER_CALLBACK_EXCEPTION), from an access violation with the instruction
    pointer at 0x0.
  • Build: RtAudio.cpp compiles clean at this branch's HEAD with
    __WINDOWS_ASIO__, MSVC 14.51, /std:c++17 — no new warnings.

Environment: Windows 11 Pro 10.0.26200 x64, Steinberg Generic Low Latency ASIO Driver
1.0.30.15.

Found while working on the standalone host in
free-audio/clap-wrapper, where "switching from
WASAPI to ASIO crashes" was on our own bug list until it turned out to be this.

Happy to adjust — for instance if you would rather pass the real ASIOTime through to
callbackEvent() than discard it, though that is a larger change than stopping the crash
needs.

RtApiAsio installed three of the four ASIO host callbacks and set
asioCallbacks.bufferSwitchTimeInfo to NULL. Any driver that calls it therefore
transfers control to address 0 and takes the process down.

asioMessages() answers kAsioSupportsTimeInfo with 0, so by the letter of the SDK
a driver should use bufferSwitch instead. Steinberg's Generic Low Latency ASIO
driver calls bufferSwitchTimeInfo regardless, crashing on the first ASIOStart().
Removing kAsioSupportsTimeInfo from the kAsioSelectorSupported list as well does
not help, so it consults neither answer.

Since the host cannot control how a third-party driver behaves, and a call
through a null function pointer is unrecoverable, supply the callback and forward
it to bufferSwitch. The time info is not used.

Fixes thestk#485. Very likely the root cause of thestk#409, and possibly thestk#443.
@garyscavone
garyscavone merged commit 521fcab into thestk:master Aug 18, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ASIO: bufferSwitchTimeInfo is left NULL, so drivers that call it crash the host at address 0 (root cause for #409)

2 participants